メモ帳を表示するPage Menu
やることを一覧できた方が、takker.iconの使い方にあっているんじゃないか どういうことか
「ここをみれば分かる」という場所がある
同様に、scrapboxでもやることを一覧できるようにするのがtakker.iconの使い方にあっているのではないだろうか?
一定期間運用できていたという実績がある
仕様
指定したprojectから検索する
その行がリンクだけの場合は、そのリンク先ページを開くようにする
押すと該当ページに飛ぶ
新しいタブでいいか
reloadボタンを押すと再読み込みが始まる
実装
他の方法
関連しないページ同士につけたくないなあtakker.icon
こっちの方がよさそうではある
既存の道具の組み合わせで実現できる
毎日開くようにすれば、そのうちわからないことが出てきたらすぐそのページを開ける宵になるかもしれない
欠点
🔳つきページを一覧出来ない
これは専用のPage Menuを作らないとだめそうだなー
「Page Menuを毎日開け」という繰り返しタスクと組み合わせればいいのか
dependencies
code:script.js
import {fetchPages, getFavicon} from '../scrapbox-api-helper/scrapboxAPI.js';
code:script.js
const id = 'memorandum';
let initialized = false;
scrapbox.PageMenu.addMenu({
title: id,
image: https://img.icons8.com/ios/180/${isDark() ? 'FFFFFF/' : ''}notepad.png,
//image: https://img.icons8.com/ios/180/FFFFFF/notepad.png,
onClick: async () => {
if (initialized) return;
await reload();
initialized = true;
},
});
本体
code:script.js
const memoPath = {project: 'takker-memex', title: 'メモ帳'};
let loading = false;
let timer = false;
async function reload() {
scrapbox.PageMenu(id).removeAllItems();
scrapbox.PageMenu(id).emitChange();
// 読み込みに時間がかかるようであれば、読み込み中の表示を出す
showLoading();
const pending = (async () => {
const items = await getMemos(memoPath.project, memoPath.title);
clearLoading();
items.forEach(({title, pathname, image}) =>
scrapbox.PageMenu(id).addItem({
title,
image,
onClick: () => window.open(https://scrapbox.io${pathname}),
})
);
})();
const pending2 = (async () => {
const items =
clearLoading();
items.forEach(({project, title, image}) => scrapbox.PageMenu(id).addItem({
title,
image,
onClick: () => window.open(https://scrapbox.io/${project}/${title}),
}));
})();
}
条件に一致するページを取得する
code:script.js
async function getTaskItems(projects, condition) {
return (await Promise.all(projects.map(async project => {
const image = await getFavicon(project);
return (await fetchPages({project}))
}))).flat();
}
特定のページからメモを取得する
[/icons/hr.icon]から[/icons/hr.icon]までを行IDつきで取得する
空行は無視する
code:script.js
async function getMemos(project, pageTitle) {
const res = await fetch(/api/pages/${project}/${pageTitle});
const {lines} = await res.json();
let start = false;
return lines.flatMap(({text, id}) => {
if (text === '/icons/hr.icon') {
start = !start;
return [];
}
if (!start) return [];
const title = text.trim();
if (title === '') return [];
/${project}/${title.match(/^\[([^\]]+)\]$/)[1]} :
/${project}/${pageTitle}#${id};
return [{
title,
pathname,
image: https://img.icons8.com/ios/180/${isDark() ? 'FFFFFF/' : ''}unchecked-checkbox.png,
}];
});
}
code:script.js
function showLoading() {
loading = true;
clearTimeout(timer);
timer = setTimeout(() => {
loading = true;
scrapbox.PageMenu(id).addItem({
title: 'Loading...',
image: https://img.icons8.com/ios/180/${isDark() ? 'FFFFFF/' : ''}loading.png,
onClick: () => {},
});
},
100,
);
}
function clearLoading() {
clearTimeout(timer);
if (loading) {
scrapbox.PageMenu(id).removeAllItems();
scrapbox.PageMenu(id).emitChange();
scrapbox.PageMenu(id).addItem({
title: 'Reload',
image: https://img.icons8.com/ios/180/${isDark() ? 'FFFFFF/' : ''}refresh.png,
onClick: () => reload(),
});
}
loading = false;
}
code:script.js
function isDark() {
}